#!/usr/bin/env python3
"""
数据分析器模块
负责对爬取的微博数据进行统计分析和处理
"""

import pandas as pd
import numpy as np
from typing import List, Dict, Any, Optional
from datetime import datetime
import re
from collections import Counter
import logging

from models.weibo_post import WeiboPost

logger = logging.getLogger('DataAnalyzer')


class DataAnalyzer:
    """数据分析器 - 负责数据统计和分析"""
    
    def __init__(self, posts: List[WeiboPost]):
        """
        初始化数据分析器
        
        Args:
            posts: 微博帖子列表
        """
        self.posts = posts
        self.df = self._to_dataframe()
        logger.info(f"数据分析器初始化完成，共 {len(posts)} 条数据")
    
    def _to_dataframe(self) -> pd.DataFrame:
        """将微博帖子列表转换为DataFrame"""
        if not self.posts:
            return pd.DataFrame()
        
        data = []
        for post in self.posts:
            # 计算总互动量
            total_engagement = post.reposts_count + post.comments_count + post.likes_count
            
            data.append({
                'id': post.id,
                'content': post.content,  # 使用 content 而不是 text
                'user_name': post.user_name,
                'user_id': post.user_id,
                'publish_time': post.publish_time,  # 使用 publish_time 而不是 created_at
                'reposts_count': post.reposts_count,
                'comments_count': post.comments_count,
                'likes_count': post.likes_count,  # 使用 likes_count 而不是 attitudes_count
                'url': post.url,
                'total_engagement': total_engagement
            })
        
        df = pd.DataFrame(data)
        
        # 数据预处理
        if not df.empty:
            df = self._preprocess_data(df)
        
        return df
    
    def _preprocess_data(self, df: pd.DataFrame) -> pd.DataFrame:
        """数据预处理"""
        # 转换时间格式
        df['publish_time_parsed'] = pd.to_datetime(
            df['publish_time'], errors='coerce', utc=True
        )
        
        # 计算文本长度
        df['content_length'] = df['content'].str.len()
        
        return df
    
    def get_basic_stats(self) -> Dict[str, Any]:
        """
        获取基础统计信息
        
        Returns:
            统计信息字典
        """
        if self.df.empty:
            return {}
        
        stats = {
            'total_posts': len(self.df),
            'total_reposts': int(self.df['reposts_count'].sum()),
            'total_comments': int(self.df['comments_count'].sum()),
            'total_likes': int(self.df['likes_count'].sum()),
            'total_engagement': int(self.df['total_engagement'].sum()),
            'avg_engagement': float(self.df['total_engagement'].mean()),
            'median_engagement': float(self.df['total_engagement'].median()),
            'max_engagement': int(self.df['total_engagement'].max()),
            'min_engagement': int(self.df['total_engagement'].min()),
            'avg_content_length': float(self.df['content_length'].mean()),
        }
        
        # 添加用户统计
        if 'user_name' in self.df.columns:
            unique_users = self.df['user_name'].nunique()
            stats['unique_users'] = int(unique_users)
            
            # 最活跃用户
            top_users = self.df.groupby('user_name').size().nlargest(5).to_dict()
            stats['top_users_by_posts'] = top_users
            
            # 最有影响力的用户（按总互动量）
            influential_users = (self.df.groupby('user_name')['total_engagement']
                               .sum().nlargest(5).to_dict())
            stats['top_users_by_engagement'] = influential_users
        
        # 时间统计（如果时间数据可用）
        if 'publish_time_parsed' in self.df.columns and not self.df['publish_time_parsed'].isna().all():
            time_stats = self._get_time_stats()
            stats.update(time_stats)
        
        logger.info("基础统计信息计算完成")
        return stats
    
    def _get_time_stats(self) -> Dict[str, Any]:
        """获取时间相关的统计信息"""
        time_stats = {}
        
        try:
            # 发布时间分布
            df_with_time = self.df.dropna(subset=['publish_time_parsed'])
            if not df_with_time.empty:
                # 按小时统计
                df_with_time['hour'] = df_with_time['publish_time_parsed'].dt.hour
                hourly_dist = df_with_time['hour'].value_counts().sort_index().to_dict()
                time_stats['hourly_distribution'] = hourly_dist
                
                # 按星期统计
                df_with_time['weekday'] = df_with_time['publish_time_parsed'].dt.day_name()
                weekday_dist = df_with_time['weekday'].value_counts().to_dict()
                time_stats['weekday_distribution'] = weekday_dist
                
                # 时间范围
                time_stats['time_range'] = {
                    'start': df_with_time['publish_time_parsed'].min().strftime('%Y-%m-%d %H:%M:%S'),
                    'end': df_with_time['publish_time_parsed'].max().strftime('%Y-%m-%d %H:%M:%S')
                }
        
        except Exception as e:
            logger.warning(f"时间统计处理失败: {e}")
        
        return time_stats
    
    def get_top_posts(self, n: int = 10, by: str = 'total_engagement') -> pd.DataFrame:
        """
        获取热门微博
        
        Args:
            n: 返回数量
            by: 排序依据字段
            
        Returns:
            热门微博DataFrame
        """
        if self.df.empty:
            return pd.DataFrame()
        
        valid_columns = ['total_engagement', 'reposts_count', 'comments_count', 'likes_count']
        if by not in valid_columns:
            logger.warning(f"排序字段 {by} 无效，使用默认字段 total_engagement")
            by = 'total_engagement'
        
        top_posts = self.df.nlargest(n, by)[[
            'user_name', 'content', 'total_engagement', 
            'reposts_count', 'comments_count', 'likes_count',
            'publish_time'
        ]].copy()
        
        # 清理文本显示
        top_posts['content_preview'] = top_posts['content'].str.slice(0, 100) + '...'
        
        logger.info(f"获取前 {n} 条热门微博（按 {by} 排序）")
        return top_posts
    
    def get_content_analysis(self) -> Dict[str, Any]:
        """
        内容分析
        
        Returns:
            内容分析结果
        """
        if self.df.empty:
            return {}
        
        analysis = {}
        
        try:
            # 文本长度分析
            content_lengths = self.df['content_length'].describe().to_dict()
            analysis['content_length_stats'] = content_lengths
            
            # 常见词汇分析
            word_stats = self._analyze_words()
            analysis.update(word_stats)
            
            # 情感分析（基础版）
            sentiment_stats = self._basic_sentiment_analysis()
            analysis['sentiment_distribution'] = sentiment_stats
            
            # 话题分析
            topic_stats = self._analyze_topics()
            analysis['topic_analysis'] = topic_stats
            
        except Exception as e:
            logger.error(f"内容分析失败: {e}")
        
        return analysis
    
    def _analyze_words(self) -> Dict[str, Any]:
        """词汇分析"""
        import jieba
        from collections import Counter
        
        # 合并所有文本
        all_text = ' '.join(self.df['content'].dropna())
        
        if not all_text.strip():
            return {}
        
        # 使用jieba分词
        words = jieba.cut(all_text)
        
        # 过滤停用词和短词
        stop_words = self._get_stop_words()
        filtered_words = [
            word for word in words 
            if len(word) > 1 and word not in stop_words and not word.isspace()
        ]
        
        # 统计词频
        word_freq = Counter(filtered_words)
        top_words = dict(word_freq.most_common(20))
        
        return {
            'total_words': len(filtered_words),
            'unique_words': len(set(filtered_words)),
            'top_words': top_words
        }
    
    def _get_stop_words(self) -> set:
        """获取中文停用词表"""
        # 基础停用词列表
        base_stop_words = {
            '的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这', '那'
        }
        return base_stop_words
    
    def _basic_sentiment_analysis(self) -> Dict[str, int]:
        """基础情感分析（基于关键词）"""
        positive_words = {'好', '喜欢', '爱', '开心', '高兴', '棒', '优秀', '完美', '精彩', '支持'}
        negative_words = {'差', '讨厌', '恨', '伤心', '难过', '糟糕', '垃圾', '失望', '反对', '恶心'}
        
        positive_count = 0
        negative_count = 0
        neutral_count = 0
        
        for text in self.df['content'].dropna():
            text_words = set(text.split())
            
            pos_match = len(text_words & positive_words)
            neg_match = len(text_words & negative_words)
            
            if pos_match > neg_match:
                positive_count += 1
            elif neg_match > pos_match:
                negative_count += 1
            else:
                neutral_count += 1
        
        return {
            'positive': positive_count,
            'negative': negative_count,
            'neutral': neutral_count
        }
    
    def _analyze_topics(self) -> Dict[str, Any]:
        """话题分析"""
        # 提取话题标签
        topics = []
        topic_pattern = r'#(.*?)#'
        
        for text in self.df['content'].dropna():
            found_topics = re.findall(topic_pattern, text)
            topics.extend(found_topics)
        
        topic_counter = Counter(topics)
        top_topics = dict(topic_counter.most_common(10))
        
        return {
            'total_topics': len(topics),
            'unique_topics': len(set(topics)),
            'top_topics': top_topics
        }
    
    def get_user_analysis(self) -> Dict[str, Any]:
        """
        用户分析
        
        Returns:
            用户分析结果
        """
        if self.df.empty or 'user_name' not in self.df.columns:
            return {}
        
        analysis = {}
        
        try:
            # 用户发帖统计
            user_posts = self.df['user_name'].value_counts()
            analysis['user_posts_distribution'] = user_posts.describe().to_dict()
            
            # 用户互动分析
            user_engagement = self.df.groupby('user_name').agg({
                'total_engagement': 'sum',
                'reposts_count': 'sum',
                'comments_count': 'sum',
                'likes_count': 'sum'
            }).round(2)
            
            analysis['user_engagement_stats'] = user_engagement.describe().to_dict()
            
        except Exception as e:
            logger.error(f"用户分析失败: {e}")
        
        return analysis
    
    def generate_report(self) -> Dict[str, Any]:
        """
        生成完整分析报告
        
        Returns:
            完整分析报告
        """
        report = {
            'basic_statistics': self.get_basic_stats(),
            'content_analysis': self.get_content_analysis(),
            'user_analysis': self.get_user_analysis(),
            'generated_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
        
        logger.info("完整分析报告生成完成")
        return report